#include <stdio.h>
#include <ctype.h>
#include <string>
#include <iostream>
using namespace std;

#define KEY 6
char *keyword[KEY] = { "for", "if", "then", "else", "while", "do" };
string id;
int num;
int token;

void lexical(FILE *fp)
{
	char x = getc(fp);
	num = 0;
	id = "";
	//id = "\0";
	//cout << "x=" << x << endl;
	while (x == ' ' || x == '\t' || x == '\n')
	{
		x = getc(fp);
	}
	if (x == 'f')
	{
		id += x;
		x = getc(fp);
		if (x == 'o')
		{
			id += x;
			x = getc(fp);
			if (x == 'r')
			{
				id += x;
				token = 1;
				//cout << id;
				return;
			}
			else
			{
				ungetc(x, fp);
				token = 10;
				return;
			}
		}
		else
		{
			ungetc(x, fp);
			token = 10;
			return;
		}
	}
	if (x == 'i')
	{
		id += x;
		x = getc(fp);
		if (x == 'f')
		{
			id += x;
			token = 2;
			return;
		}
		else
		{
			ungetc(x, fp);
			token = 10;
			return;
		}
	}
	if (x == 't')
	{
		id += x;
		x = getc(fp);
		if (x == 'h')
		{
			id += x;
			x = getc(fp);
			if (x == 'e')
			{
				id += x;
				x = getc(fp);
				if (x == 'n')
				{
					token = 3;
					//cout << id;
					return;
				}
				else
				{
					token = 10;
					ungetc(x, fp);
					return;
				}
			}
			else
			{
				ungetc(x, fp);
				token = 10;
				return;
			}
		}
		else
		{
			ungetc(x, fp);
			token = 10;
			return;
		}
	}
	if (x == 'e')
	{
		id += x;
		x = getc(fp);
		if (x == 'l')
		{
			id += x;
			x = getc(fp);
			if (x == 's')
			{
				id += x;
				x = getc(fp);
				if (x == 'e')
				{
					id += x;
					token = 4;
					//cout << id;
					return;
				}
				else
				{
					ungetc(x, fp);
					token = 10;
					return;
				}
			}
			else
			{
				ungetc(x, fp);
				token = 10;
				return;
			}
		}
		else
		{
			ungetc(x, fp);
			token = 10;
			return;
		}
	}
	if (x == 'w')
	{
		id += x;
		x = getc(fp);
		if (x == 'h')
		{
			id += x;
			x = getc(fp);
			if (x == 'i')
			{
				id += x;
				x = getc(fp);
				if (x == 'l')
				{
					id += x;
					x = getc(fp);
					if (x == 'e')
					{
						id += x;
						token = 5;
						//cout << id;
						return;
					}
					else
					{
						ungetc(x, fp);
						token = 10;
						return;
					}
				}
				else
				{
					ungetc(x, fp);
					token = 10;
					return;
				}
			}
			else
			{
				ungetc(x, fp);
				token = 10;
				return;
			}
		}
		else
		{
			ungetc(x, fp);
			token = 10;
			return;
		}
	}
	if (x == 'd')
	{
		x = getc(fp);
		if (x == 'o')
		{
			token = 6;
			id = "do";
			return;
		}
		else
		{
			ungetc(x, fp);
			token = 10;
			return;
		}
	}
	if (x == '+')
	{
		token = 13;
		id = "+";
		return;
	}
	if (x == '-')
	{
		token = 14;
		id = "-";
		return;
	}
	if (x == '*')
	{
		token = 15;
		id = "*";
		return;
	}
	if (x == '/')
	{
		token = 16;
		id = "/";
		return;
	}
	if (x == ':')
	{
		x = getc(fp);
		if (x == '=')
		{
			token = 18;
			id = ":=";
			return;
		}
		else
		{
			ungetc(x, fp);
			token = 17;
			id = ":";
			return;
		}
	}
	if (x == '<')
	{
		x = getc(fp);
		if (x == '=')
		{
			token = 22;
			id = "<=";
			return;
		}
		if (x == '>')
		{
			token = 21;
			id = "<>";
			return;
		}
		else
		{
			ungetc(x, fp);
			token = 20;
			id = "<";
			return;
		}
	}
	if (x == '>')
	{
		x = getc(fp);
		if (x == '=')
		{
			token = 24;
			id = ">=";
			return;
		}
		else
		{
			ungetc(x, fp);
			token = 23;
			id = ">";
			return;
		}
	}
	if (x == '=')
	{
		token = 25;
		id = "=";
		return;
	}
	if (x == ';')
	{
		token = 26;
		id = ";";
		return;
	}
	if (x == '(')
	{
		token = 27;
		id = "(";
		return;
	}
	if (x == ')')
	{
		token = 28;
		id = ")";
		return;
	}
	if (x == '#')
	{
		token = 0;
		id = "#";
		return;
	}
	if (isalpha(x))
	{
		id += x;
		x = getc(fp);
		while (isdigit(x) || isalpha(x))
		{
			x = getc(fp);
			id += x;
		}
		ungetc(x, fp);
		token = 10;
		return;
	}
	if (isdigit(x))
	{
		id += x;
		x = getc(fp);
		while (isdigit(x))
		{
			x = getc(fp);
			id += x;
		}
		token = 11;
		ungetc(x, fp);
		return;
	}
	//process x
	//process each regex here
	//store the result in global variables id, num, or token
	//in case of backtrack, use
	//ungetc(x, fp);
}

int main(int argc, const char *argv[])
{
	if (argc < 2) {
		printf("insufficient args\n");
		return 1;
	}
	FILE *fp = fopen(argv[1], "r");
	do {
		lexical(fp);
		switch (token) {
		case 10: cout << "(id," << id << ")" << endl; break;
		case 11: cout << "(num," << id << ")" << endl;  break;
		case -1: cout << "(error!)" << endl; break;
		default: cout << "(" << token << "," << id << ")" << endl;
		}
	} while (token != 0);


	fclose(fp);
	return 0;
}
